package com.iplant.base.utils.log;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.iplant.base.po.*;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.RetCode;
import com.iplant.base.utils.annotation.trace.TraceAPI;
import com.iplant.base.utils.annotation.trace.TraceModuleAPI;
import com.iplant.base.utils.cache.CacheUtils;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.Configuration;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.base.utils.tasker.TaskTimerUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.utils.general.LockHelper;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.DBDruidHelper;
import com.iplant.base.utils.sql.ShrisJdbcTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

public class TraceLoggerTool {

    private static Logger logger = LoggerFactory.getLogger(TraceLoggerTool.class);

    private static TraceLoggerTool Instance;

    private static LockHelper mLockHelper = LockHelper.getLock("TraceLoggerTool");

    public static final String ProjectName = Configuration.readConfigString("project.name",
            "application");

    public static final int TraceInitEnable = StringUtils.parseInt(Configuration.readConfigString("trace.log.init.enable",
            "config/config"));


    private static BPMResource<RequestMappingAPI> mBPMResource = new BPMResource<>(RequestMappingAPI.class, "接口清单");

    public static TraceLoggerTool getInstance() {
        if (Instance == null) {
            synchronized (mLockHelper) {
                if (Instance == null) {
                    Instance = new TraceLoggerTool();

                    TaskTimerUtils.AddTask(() -> {

                        List<RequestMappingAPI> wList = mBPMResource.getAll(20);
                        if (wList == null || wList.size() == 0)
                            return;
                        OutResult<Integer> wErrorCode = new OutResult<>(0);

                        ORMUtils.GetPoService(RequestMappingAPI.class).UpdatePoList(BaseUser.SysAdmin, wList, wErrorCode);
                    }, 10000, -1);

                }
            }

        }

        return Instance;
    }

    private static ShrisJdbcTemplate mShrisJdbcTemplate = null;

    private synchronized static ShrisJdbcTemplate getNameJdbcTemplate() {
        if (mShrisJdbcTemplate == null) {
            synchronized (mLockHelper) {
                if (mShrisJdbcTemplate == null) {
                    mShrisJdbcTemplate = DBDruidHelper.getInstance().getTemplate();
                }
            }
        }
        return mShrisJdbcTemplate;
    }

    public static void SaveApiLog(BaseUser wBaseUser, String wProjectName, String wURI, String wMethod, String wParams,
                                  String wRequestBody, String wResult, Calendar wRequestTime, Calendar wResponseTime, long wInterval,
                                  int wStatus) {
        ShrisJdbcTemplate shrisJdbcTemplate = getNameJdbcTemplate();
        try {
            if (wParams == null)
                wParams = "";
            if (wResult == null)
                wResult = "";
            if (wProjectName == null)
                wProjectName = "";
            if (wURI == null || wMethod == null)
                return;

            if (wParams.length() > 200) {
                wParams = wParams.substring(0, 200) + "...";
            }
            if (wRequestBody.length() > 200) {
                wRequestBody = wRequestBody.substring(0, 200) + "...";
            }
            if (wResult.length() > 200) {
                wResult = wResult.substring(0, 200) + "...";
            }

            String wSQL = StringUtils.Format(
                    "INSERT INTO {0}.mbs_apilog (CompanyID,LoginID,ProjectName,URI,Method,Params,RequestBody,Result,RequestTime,ResponseTime,IntervalTime,ResponseStatus)"
                            + " Values (:CompanyID, :LoginID,:ProjectName,:URI,:Method,:Params,:RequestBody,:Result,:RequestTime,:ResponseTime,:IntervalTime,:ResponseStatus)",
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParamsMap = new HashMap<String, Object>();
            wParamsMap.put("CompanyID", wBaseUser.getCompanyID());
            wParamsMap.put("LoginID", wBaseUser.getID());
            wParamsMap.put("ProjectName", wProjectName);
            wParamsMap.put("URI", wURI);
            wParamsMap.put("Method", wMethod.toUpperCase());
            wParamsMap.put("Params", wParams);
            wParamsMap.put("Result", wResult);
            wParamsMap.put("RequestTime", wRequestTime);
            wParamsMap.put("ResponseTime", wResponseTime);
            wParamsMap.put("RequestBody", wRequestBody);
            wParamsMap.put("IntervalTime", wInterval);
            wParamsMap.put("ResponseStatus", wStatus);
            synchronized (mLockHelper) {
                shrisJdbcTemplate.update(wSQL, wParamsMap);
            }

        } catch (Exception ex) {
            logger.error("SaveApiLog", ex);
        }
    }

    /**
     * 删除集合
     */
    public static ServiceResult<Integer> DeleteList(BaseUser wLoginUser, List<Integer> wIDList) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {

            if (wIDList == null || wIDList.size() == 0)
                return wResult;
            ShrisJdbcTemplate shrisJdbcTemplate = getNameJdbcTemplate();

            String wSql = StringUtils.Format("delete from {0}.mbs_apilog WHERE ID IN({1}) ;",
                    DBSchemas.Basic.getDBName(), StringUtils.Join(",", wIDList));
            shrisJdbcTemplate.update(wSql, new HashMap<String, Object>());
        } catch (Exception ex) {
            wResult.FaultCode += ex.getMessage();
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * @param wLoginUser
     * @param wStartTime
     * @param wEndTime
     * @param wAvgIntervalTime
     * @param wProjectName
     * @param wRequestTimes
     * @return
     */
    public static ServiceResult<List<Map<String, Object>>> GetApiLogStatistics(BaseUser wLoginUser, Calendar wStartTime,
                                                                               Calendar wEndTime, int wAvgIntervalTime, String wProjectName, String wUri, String wURIName, String wMethod, int wRequestTimes,
                                                                               Pagination wPagination) {
        ServiceResult<List<Map<String, Object>>> wResultList = new ServiceResult<List<Map<String, Object>>>();
        try {

            ShrisJdbcTemplate shrisJdbcTemplate = getNameJdbcTemplate();
            String wSQL = StringUtils.Format(
                    "select a.*,a.RequestTimes as ID ,ifnull( a1.UserControl ,2) as UserControl,a1.URIName from (SELECT t.CompanyID,t.ProjectName,"
                            + " t.URI,t.Method, count(*) as RequestTimes,sum(t.IntervalTime) as SumIntervalTime,"
                            + " avg(t.IntervalTime) as AvgIntervalTime,max(t.IntervalTime) as MaxIntervalTime,"
                            + " min(t.IntervalTime) as MinIntervalTime FROM {0}.mbs_apilog t  "
                            + " where t.RequestTime>=:wStartTime and t.RequestTime<=:wEndTime "
                            + " and t.IntervalTime>1 group by t.ProjectName,t.URI)  as a "
                            + " left join {0}.mbs_apicontrol a1 on a.CompanyID=a1.CompanyID and a.ProjectName=a1.ProjectName and a.URI=a1.URI"
                            + " where  ( :wRequestTimes <= 0 or a.RequestTimes>:wRequestTimes ) "
                            + " and (  :wProjectName = '''' or :wProjectName = a.ProjectName ) AND (:wURI =''''  OR  a.URI like :wURI)"
                            + " AND ( :wURIName =''''  OR  a1.URIName like :wURIName) "
                            + " AND ( :wMethod =''''  OR  a.Method = :wMethod) "
                            + " and ( :wAvgIntervalTime < 0 or a.AvgIntervalTime>:wAvgIntervalTime ) ",
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("wStartTime", wStartTime);
            wParamMap.put("wEndTime", wEndTime);
            wParamMap.put("wAvgIntervalTime", wAvgIntervalTime);
            wParamMap.put("wProjectName", wProjectName);
            wParamMap.put("wMethod", wMethod);
            wParamMap.put("wURI", StringUtils.isEmpty(wUri) ? "" : "%" + wUri + "%");
            wParamMap.put("wURIName", StringUtils.isEmpty(wURIName) ? "" : "%" + wURIName + "%");
            wParamMap.put("wRequestTimes", wRequestTimes);

            wResultList.Result = shrisJdbcTemplate.queryForList(wSQL, wParamMap, wPagination);

        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResultList;
    }

    public static ServiceResult<Integer> SetApiControl(BaseUser wBaseUser, String wProjectName, String wUri, String wURIName,
                                                       int wUserControl) {

        ServiceResult<Integer> wServiceResult = new ServiceResult<Integer>(0);

        try {
            ShrisJdbcTemplate shrisJdbcTemplate = getNameJdbcTemplate();

            int wID = 0;

            String wSQL = StringUtils.Format(
                    "SELECT * FROM {0}.mbs_apicontrol WHERE CompanyID=:CompanyID AND  ProjectName = :ProjectName  AND URI = :URI  ",
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("CompanyID", wBaseUser.getCompanyID());
            wParams.put("ProjectName", wProjectName);
            wParams.put("URIName", wURIName);
            wParams.put("URI", wUri);

            if (wUserControl != 1)
                wUserControl = 2;

            wParams.put("UserControl", wUserControl);

            List<Map<String, Object>> wQueryResultList = shrisJdbcTemplate.queryForList(wSQL, wParams);
            for (Map<String, Object> wReader : wQueryResultList) {
                if (wReader.containsKey("ID"))
                    wID = StringUtils.parseInt(wReader.get("ID"));
            }

            if (wID > 0) {
                wSQL = StringUtils.Format(
                        "update {0}.mbs_apicontrol set UserControl=:UserControl,URIName=:URIName  WHERE CompanyID=:CompanyID AND  ProjectName = :ProjectName  AND URI = :URI  ",
                        DBSchemas.Basic.getDBName());

            } else {
                wSQL = StringUtils.Format(
                        "insert into  {0}.mbs_apicontrol (CompanyID,ProjectName,URI,UserControl,URIName) values (:CompanyID,:ProjectName,:URI,:UserControl,:URIName)  ",
                        DBSchemas.Basic.getDBName());
            }
            shrisJdbcTemplate.update(wSQL, wParams);

        } catch (Exception ex) {
            wServiceResult.FaultCode = ex.getMessage();
            logger.error("SetApiControl", ex);
        }
        return wServiceResult;
    }

    public static ServiceResult<RequestMappingAPI> SetRequestMappingAPI(BaseUser wBaseUser, RequestMappingAPI wMappingAPI) {
        ServiceResult<RequestMappingAPI> wServiceResult = new ServiceResult<>();
        try {

            if (wMappingAPI == null) {
                wServiceResult.Result = wMappingAPI;
                wServiceResult.FaultCode += RetCode.SERVER_RST_ERROR_OUT;
                return wServiceResult;
            }

            OutResult<Integer> wErrorCode = new OutResult<>(0);
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("Uri", wMappingAPI.getUri());
            wParams.put("ProjectName", wMappingAPI.getProjectName());

            RequestMappingAPI wRequestMappingAPI = ORMUtils.GetPoService(RequestMappingAPI.class).SelectPO(wBaseUser, wParams, wErrorCode);

            wServiceResult.Result = wRequestMappingAPI;
            if (wErrorCode.Result != 0) {
                wServiceResult.AddFaultCode(wErrorCode);
                return wServiceResult;
            }
            wRequestMappingAPI.AlarmLogMin = wMappingAPI.AlarmLogMin;
            wRequestMappingAPI.Active = wMappingAPI.Active;
            wRequestMappingAPI.Pattern = wMappingAPI.Pattern;
            wRequestMappingAPI.setUserInfo(wBaseUser);
            ORMUtils.GetPoService(RequestMappingAPI.class).UpdatePo(wBaseUser, wRequestMappingAPI, wErrorCode);

            wServiceResult.Result = wRequestMappingAPI;
            wServiceResult.AddFaultCode(wErrorCode);
        } catch (Exception ex) {
            wServiceResult.FaultCode = ex.getMessage();
            logger.error("SetRequestMappingAPI", ex);
        }
        return wServiceResult;

    }


    public static ServiceResult<List<Map<String, Object>>> GetApiLog(BaseUser wBaseUser, int wUserID,
                                                                     String wProjectName, String wUri, String wURIName, String wMethod, int wUserControl, int wIntervalMin, int wIntervalMax,
                                                                     int wResponseStatus, Calendar wStartTime, Calendar wEndTime, Pagination wPagination) {

        ServiceResult<List<Map<String, Object>>> wServiceResult = new ServiceResult<List<Map<String, Object>>>();

        wServiceResult.Result = new ArrayList<>();
        try {
            ShrisJdbcTemplate shrisJdbcTemplate = getNameJdbcTemplate();
            if (wProjectName == null)
                wProjectName = "";

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1);
            if (wStartTime == null || wStartTime.compareTo(wBaseTime) < 0)
                wStartTime = wBaseTime;
            if (wEndTime == null || wEndTime.compareTo(wBaseTime) < 0)
                wEndTime = wBaseTime;
            if (wStartTime.compareTo(wEndTime) > 0)
                return wServiceResult;

            String wSQL = StringUtils.Format("SELECT t.*,ifnull(t1.UserControl,2) as UserControl,t1.URIName FROM {0}.mbs_apilog t"
                    + " left join  {0}.mbs_apicontrol t1 on t.CompanyID=t1.CompanyID "
                    + " and t.ProjectName=t1.ProjectName and t.URI=t1.URI  WHERE 1=1 "
                    + " AND (:CompanyID <= 0  OR t.CompanyID = :CompanyID) "
                    + " AND (:LoginID <= 0  OR t.LoginID = :LoginID) "
                    + " AND (:IntervalMin <= 0  OR t.IntervalTime >= :IntervalMin) "
                    + " AND (:IntervalMax <= 0  OR t.IntervalTime <= :IntervalMax) "
                    + " AND (:ResponseStatus <= 0  OR t.ResponseStatus = :ResponseStatus) "
                    + " AND (:ProjectName =''''  OR  t.ProjectName = :ProjectName) "
                    + " AND (:Method =''''  OR  t.Method = :Method) " + "AND (:URI =''''  OR  t.URI like :URI) "
                    + " AND (:URIName =''''  OR  t1.URIName like :URIName) "
                    + " AND ( :StartTime <= str_to_date(''2010-01-01'', ''%Y-%m-%d'') or :StartTime <= t.ResponseTime) "
                    + " AND ( :EndTime <= str_to_date(''2010-01-01'', ''%Y-%m-%d'') or :EndTime >= t.RequestTime) "
                    + " AND (:UserControl <= 0  OR t1.UserControl = :UserControl) ", DBSchemas.Basic.getDBName());

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("CompanyID", wBaseUser.getCompanyID());
            wParams.put("LoginID", wUserID);
            wParams.put("ProjectName", wProjectName);
            wParams.put("Method", wMethod.toUpperCase());
            wParams.put("URI", StringUtils.isEmpty(wUri) ? "" : ("%" + wUri + "%"));
            wParams.put("URIName", StringUtils.isEmpty(wURIName) ? "" : ("%" + wURIName + "%"));
            wParams.put("StartTime", wStartTime);
            wParams.put("EndTime", wEndTime);
            wParams.put("IntervalMin", wIntervalMin);
            wParams.put("IntervalMax", wIntervalMax);
            wParams.put("ResponseStatus", wResponseStatus);
            wParams.put("UserControl", wUserControl);
            wServiceResult.Result = shrisJdbcTemplate.queryForList(wSQL, wParams, wPagination);

        } catch (Exception ex) {
            wServiceResult.FaultCode = ex.getMessage();
            logger.error("GetApiLog", ex);
        }
        return wServiceResult;
    }


    private static Map<String, List<RequestMappingAPI>> mRequestMappingAPIListMap = new HashMap<>();

    private static PoService<TraceLogInfo> mTraceLogInfoPoService = null;

    private static PoService<TraceLogInfo> getTraceLogInfoPoService() {
        if (mTraceLogInfoPoService == null)
            mTraceLogInfoPoService = ORMUtils.GetPoService(TraceLogInfo.class);
        return mTraceLogInfoPoService;
    }


    public static void SetAPIMap(Map<RequestMappingInfo, HandlerMethod> requestMappings) {
        if (!mRequestMappingAPIListMap.containsKey(""))
            mRequestMappingAPIListMap.put("", new ArrayList<>());
        List<RequestMappingAPI> wRequestMappingAPIList = mRequestMappingAPIListMap.get("");
        try {
            if (requestMappings == null || requestMappings.size() == 0)
                return;
            RequestMappingAPI wRequestMappingAPI;
            for (RequestMappingInfo wRequestMappingInfo : requestMappings.keySet()) {
                if (wRequestMappingInfo == null || requestMappings.get(wRequestMappingInfo) == null)
                    continue;
                if (wRequestMappingInfo.getPatternsCondition() == null || wRequestMappingInfo.getPatternsCondition().getPatterns() == null)
                    continue;
                int i = 0;
                for (String wPatterns : wRequestMappingInfo.getPatternsCondition().getPatterns()) {

                    wRequestMappingAPI = new RequestMappingAPI();
                    wRequestMappingAPI.Active = 1;
                    wRequestMappingAPI.Uri = wPatterns;
                    wRequestMappingAPI.ProjectName = "";
                    if (wRequestMappingInfo.getMethodsCondition() != null && wRequestMappingInfo.getMethodsCondition().getMethods() != null
                            && wRequestMappingInfo.getMethodsCondition().getMethods().size() > i) {
                        wRequestMappingAPI.Method = wRequestMappingInfo.getMethodsCondition().getMethods().toArray()[i].toString().toUpperCase();
                    }
                    wRequestMappingAPI.ControllerName = requestMappings.get(wRequestMappingInfo).getBeanType().getSimpleName();

                    wRequestMappingAPI.FullName = requestMappings.get(wRequestMappingInfo).getShortLogMessage();
                    wRequestMappingAPI.Name= requestMappings.get(wRequestMappingInfo).getMethod().getName();

                    if (requestMappings.get(wRequestMappingInfo).getBeanType().isAnnotationPresent(TraceModuleAPI.class)) {
                        TraceModuleAPI wTraceModuleAPI = requestMappings.get(wRequestMappingInfo).getBeanType().getAnnotation(TraceModuleAPI.class);

                        if (wTraceModuleAPI != null) {
                            wRequestMappingAPI.ModuleName = wTraceModuleAPI.value();
                        }

                    }

                    if (requestMappings.get(wRequestMappingInfo).getMethod().isAnnotationPresent(TraceAPI.class)) {
                        TraceAPI wTraceAPI = requestMappings.get(wRequestMappingInfo).getMethod().getAnnotation(TraceAPI.class);

                        if (wTraceAPI != null) {
                            wRequestMappingAPI.Name = wTraceAPI.value();
                            wRequestMappingAPI.Pattern = wTraceAPI.Pattern();
                            wRequestMappingAPI.SuccessEnable = wTraceAPI.SuccessEnable() ? 1 : 0;
                            if (StringUtils.isNotEmpty(wTraceAPI.ModuleName()))
                                wRequestMappingAPI.ModuleName = wTraceAPI.ModuleName();
                        }
                    }

                    if (StringUtils.isEmpty(wRequestMappingAPI.ModuleName))
                        wRequestMappingAPI.ModuleName = wRequestMappingAPI.ControllerName;
                    wRequestMappingAPIList.add(wRequestMappingAPI);

                    i++;
                }
            }


        } catch (Exception ex) {
            logger.error("SetAPIMap", ex.toString());
        }

    }


    public static synchronized List<RequestMappingAPI> GetAPIMap(BaseUser wBaseUser, String wProjectName, Map<String, Object> wParams, Pagination wPagination, OutResult<Integer> wErrorCode) {
        List<RequestMappingAPI> wResult = new ArrayList<>();
        try {
            if (TraceInitEnable == 1 && !mRequestMappingAPIListMap.containsKey(wProjectName)) {

                List<RequestMappingAPI> wRequestMappingAPIProjectList = new ArrayList<>();

                Map<String, Object> wParamsTemp = new HashMap<>();

                wParamsTemp.put("ProjectName", wProjectName);

                List<RequestMappingAPI> wRequestMappingAPIListTemp = ORMUtils.GetPoService(RequestMappingAPI.class).SelectPOList(wBaseUser, wParamsTemp,
                        Pagination.getNewMaxSize(), wErrorCode);

                if (!mRequestMappingAPIListMap.containsKey(""))
                    mRequestMappingAPIListMap.put("", new ArrayList<>());
                List<RequestMappingAPI> wRequestMappingAPIList = mRequestMappingAPIListMap.get("");

                boolean isValid = false;
                RequestMappingAPI wRequestMappingAPIClone = null;
                for (RequestMappingAPI wRequestMappingAPI : wRequestMappingAPIList) {
                    isValid = false;
                    for (RequestMappingAPI wRequestMappingAPITemp : wRequestMappingAPIListTemp) {
                        if (!wRequestMappingAPI.Uri.equalsIgnoreCase(wRequestMappingAPITemp.Uri))
                            continue;
                        isValid = true;
                        wRequestMappingAPITemp.Method = wRequestMappingAPI.Method;
                        wRequestMappingAPITemp.Pattern = wRequestMappingAPI.Pattern;
                        wRequestMappingAPITemp.ControllerName = wRequestMappingAPI.ControllerName;
                        wRequestMappingAPITemp.ModuleName = wRequestMappingAPI.ModuleName;
                        wRequestMappingAPITemp.PrintLimit = wRequestMappingAPI.PrintLimit;

                        wRequestMappingAPIProjectList.add(wRequestMappingAPITemp);

                        break;
                    }
                    if (isValid)
                        continue;

                    wRequestMappingAPIClone = CloneTool.Clone(wRequestMappingAPI, RequestMappingAPI.class);
                    wRequestMappingAPIClone.ProjectName = wProjectName;
                    wRequestMappingAPIProjectList.add(wRequestMappingAPIClone);
                }
                mRequestMappingAPIListMap.put(wProjectName, wRequestMappingAPIProjectList);

                mBPMResource.addAll(wRequestMappingAPIProjectList);

            }

            wParams.put("ProjectName", wProjectName);
            wResult = ORMUtils.GetPoService(RequestMappingAPI.class).SelectPOList(wBaseUser, wParams, wPagination, wErrorCode);

        } catch (Exception ex) {
            logger.error("GetAPIMap", ex.toString());
        }
        return wResult;
    }

    public static ServiceResult<List<RequestMappingAPI>> GetAPIMap(BaseUser wBaseUser, String wProjectName, Map<String, Object> wParams, Pagination wPagination) {
        ServiceResult<List<RequestMappingAPI>> wResult = new ServiceResult<>();
        try {

            OutResult<Integer> wErrorCode = new OutResult<>(0);
            wResult.Result = GetAPIMap(wBaseUser, wProjectName, wParams, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception ex) {
            wResult.FaultCode += ex.getMessage();
            logger.error("GetAPIMap", ex.toString());
        }
        return wResult;
    }

    public static RequestMappingAPI GetAPIMap(BaseUser wBaseUser, String wProjectName, String wURI, OutResult<Integer> wErrorCode) {
        RequestMappingAPI wResult = new RequestMappingAPI();
        try {
            if (TraceInitEnable == 1) {
                Map<String, Object> wParams = new HashMap<String, Object>();
                wParams.put("Uri", wURI);
                wParams.put("ProjectName", wProjectName);

                List<RequestMappingAPI> wList = GetAPIMap(wBaseUser, wProjectName, wParams, Pagination.getNewDefault(), wErrorCode);
                if (wErrorCode.Result != 0)
                    return wResult;

                if (wList != null && wList.size() > 0)
                    wResult = wList.get(0);
            } else if (mRequestMappingAPIListMap.containsKey(wProjectName)) {
                Optional<RequestMappingAPI> wOptional = mRequestMappingAPIListMap.get(wProjectName).stream().filter(p -> p.Uri.equalsIgnoreCase(wURI)).findFirst();
                if (wOptional.isPresent())
                    wResult = wOptional.get();
            }

        } catch (Exception ex) {
            wErrorCode.Result = ExceptionTypes.Exception.getValue();
            logger.error("GetAPIMap", ex.toString());
        }
        return wResult;
    }


    /**
     * iPlantFilter 过滤器调用 其他不要调用
     * @param wBaseUser
     * @param wProjectName
     * @param wURI
     * @param wMethod
     * @param wParams
     * @param wRequestBody
     * @param wResult
     * @param wRequestTime
     * @param wResponseTime
     * @param wInterval
     */
    public static void SaveApiLogNew(BaseUser wBaseUser, String wProjectName, String wURI, String wMethod, String wParams,
                                     String wRequestBody, String wResult, Calendar wRequestTime, Calendar wResponseTime, int wInterval) {
        try {
            if (wParams == null)
                wParams = "";
            if (wResult == null)
                wResult = "";
            if (StringUtils.isEmpty(wProjectName))
                wProjectName = ProjectName;
            if (StringUtils.isEmpty(wURI))
                return;

            int wResponseStatus = RetCode.SERVER_CODE_SUC;
            String wResponseStatusTest = "\"resultCode\":" + RetCode.SERVER_CODE_SUC;
            if (!wResult.contains(wResponseStatusTest)) {
                wResponseStatus = RetCode.SERVER_CODE_ERR;
            }

            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wProjectName.startsWith("/"))
                wProjectName = wProjectName.substring(1);
            RequestMappingAPI wRequestMappingAPI = GetAPIMap(wBaseUser, wProjectName, wURI, wErrorCode);
            if (wErrorCode.Result != 0 || wRequestMappingAPI == null || wRequestMappingAPI.ID <= 0 || wRequestMappingAPI.Active != 1)
                return;

            if (wResponseStatus == RetCode.SERVER_CODE_SUC && wRequestMappingAPI.SuccessEnable != 1)
                return;

            if (wInterval < wRequestMappingAPI.AlarmLogMin)
                return;

            if (wRequestMappingAPI.PrintLimit > 0) {
                if (wParams.length() > wRequestMappingAPI.PrintLimit) {
                    wParams = wParams.substring(0, wRequestMappingAPI.PrintLimit) + "...";
                }
                if (wRequestBody.length() > wRequestMappingAPI.PrintLimit) {
                    wRequestBody = wRequestBody.substring(0, wRequestMappingAPI.PrintLimit) + "...";
                }
                if (wResult.length() > wRequestMappingAPI.PrintLimit) {
                    wResult = wResult.substring(0, wRequestMappingAPI.PrintLimit) + "...";
                }
            }

            TraceLogInfo wTraceLogInfo = new TraceLogInfo(wRequestMappingAPI);
            wTraceLogInfo.setUserInfo(wBaseUser);
            wTraceLogInfo.ProjectName = wProjectName;
            wTraceLogInfo.CompanyID = wBaseUser.CompanyID;
            wTraceLogInfo.Params = wParams;
            wTraceLogInfo.Method = wMethod;
            wTraceLogInfo.RequestBody = wRequestBody;
            wTraceLogInfo.Result = wResult;
            wTraceLogInfo.RequestTime = wRequestTime;
            wTraceLogInfo.ResponseTime = wResponseTime;
            wTraceLogInfo.IntervalTime = wInterval;
            wTraceLogInfo.ResponseStatus = wResponseStatus;
            wTraceLogInfo.CreatorName = wBaseUser.Name;
            wTraceLogInfo.EditorName = wBaseUser.Name;
            StringBuffer wStringBuffer = new StringBuffer("");
            Matcher wMatcher = Pattern.compile("\\{(?<Column>[^\\}]+)\\}", Pattern.CASE_INSENSITIVE).matcher(
                    wTraceLogInfo.Message);

            Map<String, Object> wMap = CloneTool.Clone(wTraceLogInfo, Map.class);

            List<String> wColumnNameList;

            while (wMatcher.find()) {
                wColumnNameList = StringUtils.splitList(wMatcher.group("Column"), ":");
                if (wColumnNameList == null || wColumnNameList.size() == 0 || !wMap.containsKey(wColumnNameList.get(0))) {
                    wMatcher.appendReplacement(wStringBuffer, "");

                } else {
                    if (wColumnNameList.size() > 1) {
                        wMatcher.appendReplacement(wStringBuffer, StringUtils.parseToCalendarString(wMap.get(wColumnNameList.get(0)), wColumnNameList.get(1)));
                    } else {
                        wMatcher.appendReplacement(wStringBuffer, StringUtils.parseString(wMap.get(wColumnNameList.get(0))));
                    }

                }
            }
            wMatcher.appendTail(wStringBuffer);
            wTraceLogInfo.Message = wStringBuffer.toString();
            getTraceLogInfoPoService().UpdatePo(wBaseUser, wTraceLogInfo, wErrorCode);

        } catch (Exception ex) {
            logger.error("SaveApiLogNew", ex);
        }
    }


    /**
     * 内部调用 直接保存
     * @param wBaseUser
     * @param wProjectName
     * @param wModuleName
     * @param wURI_Name
     * @param wURI
     * @param wMethod
     * @param wParams
     * @param wRequestBody
     * @param wResult
     * @param wRequestTime
     * @param wResponseTime
     * @param wResponseStatus
     * @param wInterval
     */
    public static void SaveApiLog(BaseUser wBaseUser, String wProjectName, String wModuleName, String wURI_Name, String wURI, String wMethod, String wParams,
                                  String wRequestBody, String wResult, Calendar wRequestTime, Calendar wResponseTime, int wResponseStatus, int wInterval) {
        try {
            if (wParams == null)
                wParams = "";
            if (wResult == null)
                wResult = "";
            if (StringUtils.isEmpty(wProjectName))
                wProjectName = ProjectName;
            if (StringUtils.isEmpty(wURI))
                return;


            OutResult<Integer> wErrorCode = new OutResult<>(0);


            TraceLogInfo wTraceLogInfo = new TraceLogInfo();
            wTraceLogInfo.setUserInfo(wBaseUser);
            wTraceLogInfo.Name = wURI_Name;
            wTraceLogInfo.URI = wURI;
            wTraceLogInfo.ModuleName = wModuleName;
            wTraceLogInfo.Message = "{CreatorName}在{RequestTime:yyyy-MM-dd HH:mm:ss}执行了{ModuleName}模块的{Name}操作";
            wTraceLogInfo.ProjectName = wProjectName;
            wTraceLogInfo.CompanyID = wBaseUser.CompanyID;
            wTraceLogInfo.Params = wParams;
            wTraceLogInfo.Method = wMethod;
            wTraceLogInfo.RequestBody = wRequestBody;
            wTraceLogInfo.Result = wResult;
            wTraceLogInfo.RequestTime = wRequestTime;
            wTraceLogInfo.ResponseTime = wResponseTime;
            wTraceLogInfo.IntervalTime = wInterval;
            wTraceLogInfo.ResponseStatus = wResponseStatus;
            wTraceLogInfo.CreatorName = wBaseUser.Name;
            wTraceLogInfo.EditorName = wBaseUser.Name;
            StringBuffer wStringBuffer = new StringBuffer("");
            Matcher wMatcher = Pattern.compile("\\{(?<Column>[^\\}]+)\\}", Pattern.CASE_INSENSITIVE).matcher(
                    wTraceLogInfo.Message);

            Map<String, Object> wMap = CloneTool.Clone(wTraceLogInfo, Map.class);

            List<String> wColumnNameList;

            while (wMatcher.find()) {
                wColumnNameList = StringUtils.splitList(wMatcher.group("Column"), ":");
                if (wColumnNameList == null || wColumnNameList.size() == 0 || !wMap.containsKey(wColumnNameList.get(0))) {
                    wMatcher.appendReplacement(wStringBuffer, "");

                } else {
                    if (wColumnNameList.size() > 1) {
                        wMatcher.appendReplacement(wStringBuffer, StringUtils.parseToCalendarString(wMap.get(wColumnNameList.get(0)), wColumnNameList.get(1)));
                    } else {
                        wMatcher.appendReplacement(wStringBuffer, StringUtils.parseString(wMap.get(wColumnNameList.get(0))));
                    }

                }
            }
            wMatcher.appendTail(wStringBuffer);
            wTraceLogInfo.Message = wStringBuffer.toString();
            getTraceLogInfoPoService().UpdatePo(wBaseUser, wTraceLogInfo, wErrorCode);

        } catch (Exception ex) {
            logger.error("SaveApiLog", ex);
        }
    }
}
